#ifndef BUFFER_H_
#define BUFFER_H_

#include "base/base.h"

namespace unet {
class Buffer {
  Buffer();
  ~Buffer();

  void Write(const char* buf, uint32 size);
  template<typename Type>
  void Write(const Type& t) {
    Write((char*) &t, sizeof(t));
  }

  char* Read(uint32 size);
  template<typename Type>
  void Read(Type* t) {
    ::memcpy(t, Read(sizeof(*t)), sizeof(*t));
  }

  uint32 WriteableSize() const {
    return end_ - wpos_;
  }
  uint32 ReadableSize() const {
    return wpos_ - rpos_;
  }
  uint32 BufferSize() const {
    return end_ - mem_;
  }

  void SkipRpos(uint32 size) {
    rpos_ += size;
    CHECK_LE(rpos_, wpos_);
  }
  void SkipWpos(uint32 size) {
    wpos_ += size;
    CHECK_E(wpos_, end_);
  }
  char* PeekR(uint32 n) const {
    CHECK(rpos_ +n >= wpos_);
    return rpos_ + n;
  }

 private:
  char* mem_;
  char* end_;
  char* rpos_;
  char* wpos_;

  void EnSureLeftSize(uint32 size);

  DISALLOW_COPY_AND_ASSIGN(Buffer);
};

}

#endif
